package com.example.soss.interceptor;

import com.alibaba.fastjson.JSON;
import com.example.soss.annotation.RefreshLimit;
import com.example.soss.entity.Result;
import com.example.soss.entity.ResultEnum;
import com.example.soss.entity.Student;
import com.example.soss.util.RefreshLimitUtil;
import com.example.soss.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@Slf4j
public class RefreshLimitInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {

            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RefreshLimit refreshLimit = handlerMethod.getMethodAnnotation(RefreshLimit.class);
            if (refreshLimit != null) {
                int count = refreshLimit.maxCount();

                String key;
                Student student = UserContextHolder.getUser();
                if (student == null) {
                    key = request.getRemoteAddr();
                } else {
                    key = request.getRequestURI() + student.getUsername();
                }

                AtomicInteger atomicInteger = RefreshLimitUtil.get(key);
                if (atomicInteger == null) {
                    RefreshLimitUtil.set(key, new AtomicInteger(1));
                } else if (atomicInteger.get() <= count) {
                    atomicInteger.incrementAndGet();
                    RefreshLimitUtil.set(key, atomicInteger);
                } else {
                    String xRequestedWith = request.getHeader("x-requested-with");
                    if ("XMLHttpRequest".equals(xRequestedWith)) {
                        response.setContentType("application/json");
                        response.setCharacterEncoding("UTF-8");
                        PrintWriter writer = response.getWriter();
                        writer.write(JSON.toJSONString(Result.failure(ResultEnum.LIMIT)));
                        writer.close();
                    } else {
                        response.sendRedirect(request.getContextPath() + "/400");
                    }
                    log.info("接口防刷拦截。。。");
                    return false;
                }

            }

        }
        return true;

    }
}
